<template>
  <view class="zb-tabs__nav zb-tabs__nav--line" >
    <scroll-view
        :scroll-x="scrollable"
        :scroll-left="scrollLeft"
        :show-scrollbar="false"
        scroll-with-animation
        class="zb-tabs__wrapper__scroll-view"
    >
      <view class="zb-tabs__nav_inner">
        <view class="zb-tab" :class="[{
		        'zb-tab--shrink':shrink,
            'zb-tab--active':activeIndex===index,
            'zb-tab--disabled':item.disabled,
          }]" ref="tab" v-for="item,index in data" :key="item.value" @click="changeTab(item,index)">
          <view class="zb-tab__text zb-tab__text--ellipsis" :style="[activeIndex===index&&activeStyle]">
            {{item.name}}</view>
        </view>
        <view class="zb-tabs__line" :style="[lineStyle]"></view>
      </view>
    </scroll-view>
  </view>
</template>

<script>
export default {
  options: {
    // #ifdef MP-WEIXIN
    // 微信小程序中 options 选项
    multipleSlots: true, //  在组件定义时的选项中启动多slot支持，默认启用
    styleIsolation: "isolated",  //  启动样式隔离。当使用页面自定义组件，希望父组件影响子组件样式时可能需要配置。具体配置选项参见：微信小程序自定义组件的样式
    addGlobalClass: true, //  表示页面样式将影响到自定义组件，但自定义组件中指定的样式不会影响页面。这个选项等价于设置 styleIsolation: apply-shared
    virtualHost: true,  //  将自定义节点设置成虚拟的，更加接近Vue组件的表现。我们不希望自定义组件的这个节点本身可以设置样式、响应 flex 布局等，而是希望自定义组件内部的第一层节点能够响应 flex 布局或者样式由自定义组件本身完全决定
    // #endif
  },
  props: {
    // 开启收缩布局
    shrink:{
      type: Boolean,
      default: false
    },
    // 底部条宽度，
    lineWidth: {
      type: String,
      default: ''
    },
    lineColor: {
      type: String,
      default: '#ee0a24'
    },
    activeStyle: {
      type: Object,
      default: () => {}
    },
    value: {
      type: [Number, String],
      default: 0,
    },
    data: {
      type: Array,
      default: () => []
    },
    // 菜单是否可滚动
    scrollable:{
      type: Boolean,
      default: true
    }
  },

  data() {
    return {
      scrollLeft: 0,
      lineStyle: {},
      inited:true,
      initTime:null,
      activeIndex: this.value
    }
  },
  unmounted(){
    this.initTime = null
  },
  mounted() {
    this.setLine()
  },
  watch: {
    value: {
      handler(val) {
        this.setCurrentIndexByName(val);
        this.$nextTick(()=>{
          this.setLine()
        })
        let item = this.data.find(item=>item.value===val)

        if(item){

        }
        this.$emit('change', {
          ...item
        });
      },
      immediate: true
    }
  },
  methods: {
    isNumeric(val) {
      return /^\d+(\.\d+)?$/.test(val);
    },
    addUnit(value) {
      if (value == null) {
        return undefined
      }
      value = String(value);
      return this.isNumeric(value) ? `${value}px` : value;
    },
    setCurrentIndexByName(val) {
      this.activeIndex = this.data.findIndex(item => item.value === val)
    },

    async getWidth() {
      return new Promise((resolve) => {
        let view = uni.createSelectorQuery().in(this).selectAll(".zb-tab");
        view.boundingClientRect(data => {
          resolve(data)
        }).exec();
      })
    },

    async getWrapWidth(){
      return new Promise(resolve => {
        let view = uni.createSelectorQuery().in(this).select(".zb-tabs__nav");
        view.boundingClientRect(data => {
          resolve(data)
        }).exec();
      })
    },

    /**
     * @ 滑动
     * @param lineOffsetLeft 当前tab 距离左边的距离
     * @param itemTab 当前tab滑块的位置
     * @returns {Promise<void>}
     */
    async scrollLeftTo(lineOffsetLeft,itemTab){
      let tabNav = await this.getWrapWidth()
      this.scrollLeft = lineOffsetLeft - (tabNav.width - itemTab.width)/2

    },

    async setLine() {
      let tabs = await this.getWidth()
      let itemTab = tabs[this.activeIndex]
      if(!itemTab)return

      // 获取滑块该移动的位置
      let currentBeforeArr = tabs
          .slice(0, this.activeIndex)

      let lineOffsetLeft = currentBeforeArr
          .reduce((total, curr) => {
            return total + curr.width
          }, 0);
      const left = lineOffsetLeft + itemTab.width/2;
      this.scrollLeftTo(lineOffsetLeft,itemTab)
      const lineStyle = {
        width: this.addUnit(this.lineWidth),
        transform: `translateX(${left}px) translateX(-50%)`,
        background:this.lineColor
      };

      if(this.inited){
        lineStyle.transitionDuration = '0s'
        if(this.inited){
          this.initTime = setTimeout(() => {
            this.inited = false
          }, 10);
        }
      }

      this.lineStyle = lineStyle;
    },

    changeTab(item, index) {
      if(item.disabled)return
      this.activeIndex = index
      this.setLine()
      this.$emit('input', item.value);
      this.$emit('click-tab',item)

    }
  }
}
</script>

<style lang="scss" scoped>
$zb-tabs-bottom-bar-color: var(--zb-tabs-bottom-bar-color);

.zb-tabs__nav--line {
  box-sizing: content-box;
  height: 100%;
}
.zb-tabs__nav_inner{
  width: 100%;
  height: 100%;
  position: relative;
  display: -webkit-box;
  display: -webkit-flex;
  display: flex;
  background-color: #fff;
  -webkit-user-select: none;
  user-select: none;
}
.zb-tabs__wrapper__scroll-view{
  height: 100%;
  width: 100%;
}
.zb-tabs__nav {
  width: 100%;
  ::v-deep{
    ::-webkit-scrollbar {
      display: none;
      width: 0!important;
      height: 0!important;
      -webkit-appearance: none;
      background: transparent;
    }
  }
}

.zb-tab {
  position: relative;
  display: -webkit-box;
  display: -webkit-flex;
  display: flex;
  -webkit-box-flex: 1;
  -webkit-flex: 1;
  flex: 1;
  -webkit-box-align: center;
  -webkit-align-items: center;
  align-items: center;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
  justify-content: center;
  box-sizing: border-box;
  padding: 0 4px;
  color: #646566;
  font-size: 14px;
  line-height: 20px;
  /* #ifdef H5 */
  cursor: pointer;
  /* #endif */

}

.zb-tab__text--ellipsis {
  display: -webkit-box;
  overflow: hidden;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
}

.zb-tab--active {
  color: #323233;
  font-weight: bold;

}

.zb-tabs__line {
  position: absolute;
  bottom: 2px;
  left: 0;
  z-index: 1;
  width: 40px;
  height: 3px;
  background-color: $zb-tabs-bottom-bar-color;
  border-radius: 3px;
  transition-duration: 0.3s;
}
.zb-tab--disabled{
  cursor: not-allowed;
  .zb-tab__text{
    color: #c8c9cc;
  }
}
.zb-tab--shrink {
  flex: none;
  padding: 0 8px;
}

</style>
